package Model;

import bl.*;

public class TokenManager
{
	TokenClassesManagerI m_manager;
	PublicParametersI m_ppPO;
	VEBTokensGeneratorI m_POsideTokenGenerator;
	byte[] m_ppBytes;
	
	private static TokenManager m_Instance;
	
	private TokenManager()
	{
		// via the this interface you create instances of the relevant methods.
		m_manager = new IntegersTokenClassesManager();
		
		// contains the public parameters
		try {
			m_ppPO = m_manager.CreatePublicParameters(1024);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// The PO knows only the public parameters
		try {
			m_POsideTokenGenerator = m_manager.CreateVEBTokenGenerator(m_ppPO);
		} catch (IneligibleTypeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// 0. The client and her friend pull the public parameters as byte[] representation and generate the public-parameters as an object.
		m_ppBytes = m_ppPO.GetBytes();
	}
	
	public static TokenManager getInstance()
	{
		if (m_Instance == null)
		{
			m_Instance = new TokenManager();
		}
		
		return m_Instance;
	}
	
	public byte[] getPublicParams()
	{
		return m_ppBytes;
	}

	public int getTokenLength() 
	{
		return m_ppPO.GetTokenLengthBytes();
	}
	
	public int getMessageLength() 
	{
		return 1024;
	}

	public int getProofLength() 
	{
		return m_ppPO.GetProofLengthBytes();
	}

	public boolean isProofValid(byte[] clientProofBytes, byte[] clientPullTokenBytes) throws IneligibleTypeException 
	{
		NIZKproofI proofReceivedByPO = m_POsideTokenGenerator.ParseProofBytes(clientProofBytes);
		VEBTokenI recipientToken = m_POsideTokenGenerator.ParseTokenBytes(clientPullTokenBytes);
		if (recipientToken.Verify(proofReceivedByPO, m_ppPO))
		{
			return true;
		}
		
		return false;
	}
}
